package bdd.sql.server.configuration;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import tools.FileUtils;
import tools.PasswordSecurity;
import tools.StringUtils;
import tools.math.Math_;

import bdd.sql.server.bean.Configuration;
import bdd.sql.server.bean.Keystore;
import bdd.sql.server.bean.RequestToken;
import bdd.sql.server.bean.ServerAuth;
import bdd.sql.server.bean.ServerCentral;
import bdd.sql.server.bean.Camera;
import bdd.sql.server.bean.Encryption;
import bdd.sql.server.bean.Log;
import bdd.sql.server.bean.ServerSite;
import bdd.sql.server.bean.User;
import bdd.sql.server.bean.User_Log;
import bdd.sql.server.bean.Video;
import bdd.sql.server.bean.ServerWeb;
import bdd.sql.server.hibernate.HibernateUtil;
import bdd.sql.server.bean.ServerStorage;

import enumTypes.Civility;
import enumTypes.LogType;
import enumTypes.Rank;

/**
 * Classe de test pour la base de données.
 * @author Guillaume Pocas & Jean-Fraçois Augé
 */
public class DatabaseConfiguration {

	public static void storeConfigurations() {
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();

		// supprimer les configurations des serveurs
		List<ServerAuth> list_1 = session.createCriteria(ServerAuth.class).list();
		System.out.println("\tServerAuth");
		for(ServerAuth s : list_1) {
			System.out.println(s);
			s.setConf(null);
			session.save(s);
		}

		List<ServerCentral> list_2 = session.createCriteria(ServerCentral.class).list();
		System.out.println("\tServerCentral");
		for(ServerCentral s : list_2) {
			System.out.println(s);
			s.setConf(null);
			session.save(s);
		}

		List<ServerSite> list_3 = session.createCriteria(ServerSite.class).list();
		System.out.println("\tServerSite");
		for(ServerSite s : list_3) {
			System.out.println(s);
			s.setConf(null);
			session.save(s);
		}

		List<ServerStorage> list_4 = session.createCriteria(ServerStorage.class).list();
		System.out.println("\tServerStorage");
		for(ServerStorage s : list_4) {
			System.out.println(s);
			s.setConf(null);
			session.save(s);
		}

		List<ServerWeb> list_5 = session.createCriteria(ServerWeb.class).list();
		System.out.println("\tServerWeb");
		for(ServerWeb s : list_5) {
			System.out.println(s);
			s.setConf(null);
			session.save(s);
		}

		// vider les tables configurations
		List<Configuration> list_6 = session.createCriteria(Configuration.class).list();
		System.out.println("\tConfiguration");
		for(Configuration c : list_6) {
			System.out.println(c);
			session.delete(c);
		}

		tx.commit();



		// créer les entrées configuration dans la base
		tx = session.beginTransaction();

		File conf_file = null;
		long weight = 0;
		byte[] conf_content = null;

		// auth
		conf_file = new File("archives/KrakenAuth.tar.gz");
		weight = conf_file.length();
		conf_content = FileUtils.fileToByteArray(conf_file, Math_.safeLongToInt(weight));
		Configuration auth_conf = new Configuration("/root/KrakenAuth.tar.gz", conf_content);
		session.save(auth_conf);

		conf_file = new File("archives/KrakenCentral.tar.gz");
		weight = conf_file.length();
		conf_content = FileUtils.fileToByteArray(conf_file, Math_.safeLongToInt(weight));
		Configuration central_conf = new Configuration("/root/KrakenCentral.tar.gz", conf_content);
		session.save(central_conf);

		conf_file = new File("archives/KrakenSite.tar.gz");
		weight = conf_file.length();
		conf_content = FileUtils.fileToByteArray(conf_file, Math_.safeLongToInt(weight));
		Configuration site_conf = new Configuration("/root/KrakenSite.tar.gz", conf_content);
		session.save(site_conf);

		conf_file = new File("archives/KrakenStorage.tar.gz");
		weight = conf_file.length();
		conf_content = FileUtils.fileToByteArray(conf_file, Math_.safeLongToInt(weight));
		Configuration storage_conf = new Configuration("/root/KrakenStorage.tar.gz", conf_content);
		session.save(storage_conf);

		tx.commit();


		// relier les configurations au bons serveurs
		tx = session.beginTransaction();

		for(ServerAuth s : list_1) {
			s.setConf(auth_conf);
			session.save(s);
		}

		for(ServerCentral s : list_2) {
			s.setConf(central_conf);
			session.save(s);
		}

		for(ServerSite s : list_3) {
			s.setConf(site_conf);
			session.save(s);
		}

		for(ServerStorage s : list_4) {
			s.setConf(storage_conf);
			session.save(s);
		}

		tx.commit();
		session.close();
	}

	/**
	 * Données de tests pour la base de données.
	 */
	public static void delete_datas() {
		//vidage des tables

		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();

		List<User> list = session.createCriteria(User.class).list();
		System.out.println("\tuser_cameras");
		for(User u : list){
			System.out.println(u);
			Set<Camera> cameras = u.getCameras();
			u.getCameras().removeAll(cameras);
			session.save(u);

			for(Camera cam : cameras) {
				cam.getUsers().remove(u);
				session.save(cam);
			}
		}

		List<Video> list13 = session.createCriteria(Video.class).list();
		System.out.println("\tVideo");
		for(Video c : list13){
			System.out.println(c);
			session.delete(c);
		}

		List<Keystore> list2 = session.createCriteria(Keystore.class).list();
		System.out.println("\tKeystore");
		for(Keystore c : list2){
			System.out.println(c);
			session.delete(c);
		}

		List<RequestToken> list3 = session.createCriteria(RequestToken.class).list();
		System.out.println("\tRequestToken");
		for(RequestToken c : list3){
			System.out.println(c);
			session.delete(c);
		}

		List<Camera> list1 = session.createCriteria(Camera.class).list();
		System.out.println("\tCamera");
		for(Camera c : list1){
			System.out.println(c);
			session.delete(c);
		}

		List<ServerSite> list15 = session.createCriteria(ServerSite.class).list();
		System.out.println("\tSiteServer");
		for(ServerSite c : list15){
			System.out.println(c);
			session.delete(c);
		}

		List<Encryption> list4 = session.createCriteria(Encryption.class).list();
		System.out.println("\tEncryption");
		for(Encryption c : list4){
			System.out.println(c);
			session.delete(c);
		}

		List<Log> list6 = session.createCriteria(Log.class).list();
		System.out.println("\tLog");
		for(Log c : list6){
			System.out.println(c);
			session.delete(c);
		}

		List<ServerStorage> list9 = session.createCriteria(ServerStorage.class).list();
		System.out.println("\tStorageServer");
		for(ServerStorage c : list9){
			System.out.println(c);
			session.delete(c);
		}

		List<ServerWeb> list14 = session.createCriteria(ServerWeb.class).list();
		System.out.println("\tWebServer");
		for(ServerWeb c : list14){
			System.out.println(c);
			session.delete(c);
		}

		List<User_Log> list11 = session.createCriteria(User_Log.class).list();
		System.out.println("\tUser_Log");
		for(User_Log c : list11)
			System.out.println(c);

		List<User> list12 = session.createCriteria(User.class).list();
		System.out.println("\tUser");
		for(User c : list12){
			System.out.println(c);
			session.delete(c);
		}

		List<ServerAuth> list8 = session.createCriteria(ServerAuth.class).list();
		System.out.println("\tServerAuth");
		for(ServerAuth c : list8){
			System.out.println(c);
			session.delete(c);
		}

		List<ServerCentral> list5 = session.createCriteria(ServerCentral.class).list();
		System.out.println("\tCentralServer");
		for(ServerCentral c : list5){
			System.out.println(c);
			session.delete(c);
		}

		tx.commit();
		session.close();
	}

	public static void add_datas(){

		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();

		//ajout des données

		/*
		 * TODO
		 * Classes dont on ajoute aucune données :
		 * Configuration (traité par une autre fonction)
		 * Encryption
		 * Keystore
		 * Log
		 * RequestToken
		 * User_Log
		 * Video
		 */

		//User : admin
		List<User> resultats = session.createCriteria(User.class).list();
		boolean exist = false;

		for(User usr : resultats)
			if(usr.getUser_mail().equalsIgnoreCase("admin")) exist = true;

		if(!exist){
			String seed = StringUtils.generateRandomString(12);
			User userAdmin = new User("admin", "a", "admin", Rank.Administrateur, Civility.Monsieur, seed);
			session.save(userAdmin);

			byte[] password = PasswordSecurity.sha256_2("admin", userAdmin.getUser_seedPwd());
			String b64 = StringUtils.toBase64(password);

			userAdmin.setUser_pwd(b64);
			userAdmin.setUser_firstcon(0);
			session.save(userAdmin);

			tx.commit();
			tx = session.beginTransaction();
		}
		
		String clusterCentral = "cluster_central";
		String clusterSite1 = "cluster_site1";
		String clusterSite2 = "cluster_site2";

		//ServerCentral
		ServerCentral serverCentral = new ServerCentral("SRV-GL01", "192.168.2.91", clusterCentral);
		session.save(serverCentral);

		//ServerWeb
		ServerWeb serverWeb = new ServerWeb("SRV-WEB01", "192.168.2.51", clusterCentral);
		session.save(serverWeb);

		//ServerAuth
		ServerAuth serverAuth = new ServerAuth("SRV-AUTH01", "192.168.2.92", clusterCentral);
		session.save(serverAuth);

		//ServerSite
		ServerSite site1 = new ServerSite("SRV-LO01", "192.168.2.41", clusterSite1, "", serverCentral);
		session.save(site1);
		serverCentral.addServerSite(site1);
		ServerSite site2 = new ServerSite("SRV-LO02", "192.168.2.60", clusterSite2, "", serverCentral);
		session.save(site2);
		serverCentral.addServerSite(site2);
		session.save(serverCentral);
		
		//Camera
		//Camera cam_test = new Camera("Cam_Local", "dshow://", "none", "Webcam", ss);
		Camera cam_1 = new Camera("cam42", "192.168.2.42", "D-Link", "DCS-932L", site1);
		Camera cam_4 = new Camera("cam45", "192.168.2.45", "D-Link", "DCS-932L", site1);
		site1.addCamera(cam_1);
		site1.addCamera(cam_4);
		session.save(cam_1);
		session.save(cam_4);
		session.save(site1);
		Camera cam_2 = new Camera("cam43", "192.168.2.43", "D-Link", "DCS-932L", site2);
		Camera cam_3 = new Camera("cam44", "192.168.2.44", "D-Link", "DCS-932L", site2);
		site2.addCamera(cam_2);
		site2.addCamera(cam_3);
		session.save(cam_2);
		session.save(cam_3);
		session.save(site2);
		
		//ServerStorage
		ServerStorage storageCentral = new ServerStorage("SRV-ST00", "192.168.2.93", clusterCentral);
		storageCentral.setCentral(serverCentral);
		serverCentral.setServerStorage(storageCentral);
		session.save(storageCentral);
		session.save(serverCentral);
		ServerStorage storageSite1 = new ServerStorage("SRV-ST01", "192.168.2.50", clusterSite1);
		storageSite1.setSite(site1);
		site1.setServerStorage(storageSite1);
		session.save(storageSite1);
		session.save(site1);
		ServerStorage storageSite2 = new ServerStorage("SRV-ST02", "192.168.2.61", clusterSite2);
		storageSite2.setSite(site2);
		site2.setServerStorage(storageSite2);
		session.save(storageSite2);
		session.save(site2);

		tx.commit();

		//fermeture de session
		session.close();
		
		System.out.println("Fin ajout données");
	}

	public static void main(String[] args) {
		//DatabaseConfiguration.storeConfigurations();
		//DatabaseConfiguration.delete_datas();
		DatabaseConfiguration.add_datas();
	}

}
